import { ref, onMounted, onUnmounted } from 'vue'

interface IntersectionObserverOptions {
  threshold?: number | number[]
  rootMargin?: string
  root?: Element | null
  once?: boolean
}

export function useIntersectionObserver(
  callback: (entry: IntersectionObserverEntry) => void,
  options: IntersectionObserverOptions = {}
) {
  const elementRef = ref<Element | null>(null)
  const isIntersecting = ref(false)

  const {
    threshold = 0.1,
    rootMargin = '0px',
    root = null,
    once = false
  } = options

  let observer: IntersectionObserver | null = null

  const createObserver = () => {
    if (!elementRef.value) return

    observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          isIntersecting.value = entry.isIntersecting

          if (entry.isIntersecting) {
            callback(entry)

            if (once && observer) {
              observer.unobserve(elementRef.value!)
            }
          }
        })
      },
      {
        threshold,
        rootMargin,
        root
      }
    )

    observer.observe(elementRef.value)
  }

  const cleanup = () => {
    if (observer) {
      observer.disconnect()
      observer = null
    }
  }

  onMounted(() => {
    createObserver()
  })

  onUnmounted(() => {
    cleanup()
  })

  return {
    elementRef,
    isIntersecting
  }
}

// 用于动画观察的封装
export function useAnimateOnScroll(elementId: string, animationClass: string, threshold = 0.1) {
  const { elementRef, isIntersecting } = useIntersectionObserver(
    (entry) => {
      if (entry.isIntersecting) {
        entry.target.classList.add(animationClass)
      }
    },
    { threshold, once: true }
  )

  onMounted(() => {
    const element = document.getElementById(elementId)
    if (element) {
      elementRef.value = element
    }
  })

  return { isIntersecting }
}

// 用于计数器动画的观察
export function useCountUpOnScroll(elementId: string, target: number, duration = 2000) {
  const { elementRef, isIntersecting } = useIntersectionObserver(
    (entry) => {
      if (entry.isIntersecting) {
        animateCountUp(entry.target, target, duration)
      }
    },
    { threshold: 0.5, once: true }
  )

  onMounted(() => {
    const element = document.getElementById(elementId)
    if (element) {
      elementRef.value = element
    }
  })

  return { isIntersecting }
}

// 计数器动画函数
function animateCountUp(element: Element, target: number, duration: number) {
  const start = 0
  const increment = target / (duration / 16) // 60fps
  let current = start

  const animate = () => {
    current += increment
    if (current < target) {
      element.textContent = Math.floor(current).toString()
      requestAnimationFrame(animate)
    } else {
      element.textContent = target.toString()
    }
  }

  animate()
}

// 用于多个元素的批量观察
export function useBatchIntersectionObserver(
  elements: string[],
  callback: (entries: IntersectionObserverEntry[]) => void,
  options: IntersectionObserverOptions = {}
) {
  const { threshold = 0.1, rootMargin = '0px', root = null } = options

  let observer: IntersectionObserver | null = null

  const createObserver = () => {
    const elementRefs = elements.map(id => document.getElementById(id)).filter(Boolean) as Element[]

    if (elementRefs.length === 0) return

    observer = new IntersectionObserver(callback, {
      threshold,
      rootMargin,
      root
    })

    elementRefs.forEach(element => {
      observer!.observe(element)
    })
  }

  const cleanup = () => {
    if (observer) {
      observer.disconnect()
      observer = null
    }
  }

  onMounted(() => {
    createObserver()
  })

  onUnmounted(() => {
    cleanup()
  })

  return { cleanup }
}

// 获取元素可见性比例
export function useElementVisibility(elementId: string) {
  const visibilityRatio = ref(0)
  const isVisible = ref(false)

  const { elementRef } = useIntersectionObserver(
    (entry) => {
      visibilityRatio.value = entry.intersectionRatio
      isVisible.value = entry.isIntersecting
    },
    { threshold: Array.from({ length: 101 }, (_, i) => i / 100) }
  )

  onMounted(() => {
    const element = document.getElementById(elementId)
    if (element) {
      elementRef.value = element
    }
  })

  return {
    visibilityRatio,
    isVisible
  }
}

// 视差滚动效果
export function useParallax(elementId: string, speed = 0.5) {
  const parallaxOffset = ref(0)

  const handleScroll = () => {
    const element = document.getElementById(elementId)
    if (element) {
      const scrolled = window.pageYOffset
      const rate = scrolled * -speed
      parallaxOffset.value = rate
      element.style.transform = `translateY(${rate}px)`
    }
  }

  onMounted(() => {
    window.addEventListener('scroll', handleScroll)
  })

  onUnmounted(() => {
    window.removeEventListener('scroll', handleScroll)
  })

  return { parallaxOffset }
}